import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:uuid/uuid.dart';

class VivoAuth {
  static const Utf8Codec utf8 = Utf8Codec();

  static String generateRandomString(int len) {
    const chars =
        '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    final rnd = Random();
    final sb = StringBuffer();
    for (var i = 0; i < len; i++) {
      sb.write(chars[rnd.nextInt(chars.length)]);
    }
    return sb.toString();
  }

  static String generateCanonicalQueryString(String queryParams) {
    if (queryParams.isEmpty) {
      return '';
    }

    final params = <String, String>{};
    final param = queryParams.split('&');
    for (final item in param) {
      final pair = item.split('=');
      if (pair.length == 2) {
        params[pair[0]] = pair[1];
      } else {
        params[pair[0]] = '';
      }
    }
    final keys = params.keys.toList()..sort();
    final sb = StringBuffer();
    var first = true;
    for (final key in keys) {
      if (!first) {
        sb.write('&');
      }
      final item =
          '${Uri.encodeComponent(key)}=${Uri.encodeComponent(params[key]!)}';
      sb.write(item);
      first = false;
    }

    return sb.toString();
  }

  static String generateSignature(String appKey, String signingString) {
    try {
      final key = utf8.encode(appKey);
      final bytes = utf8.encode(signingString);
      final hmacSha256 = Hmac(sha256, key);
      final digest = hmacSha256.convert(bytes);
      return base64.encode(digest.bytes);
    } catch (err) {
      print('create sign exception: $err');
      return '';
    }
  }

  static Map<String, String> generateAuthHeaders(String appId, String appKey,
      String method, String uri, String queryParams) {
    final nonce = generateRandomString(8);
    final timestamp =
    (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString();
    final canonicalQueryString = generateCanonicalQueryString(queryParams);
    final signedHeadersString =
        'x-ai-gateway-app-id:$appId\nx-ai-gateway-timestamp:$timestamp\nx-ai-gateway-nonce:$nonce';

    final fields = [
      method,
      uri,
      canonicalQueryString,
      appId,
      timestamp,
      signedHeadersString
    ];
    final buf = StringBuffer();
    for (var i = 0; i < fields.length; i++) {
      if (i > 0) {
        buf.write('\n');
      }
      buf.write(fields[i]);
    }

    final headers = <String, String>{
      'X-AI-GATEWAY-APP-ID': appId,
      'X-AI-GATEWAY-TIMESTAMP': timestamp,
      'X-AI-GATEWAY-NONCE': nonce,
      'X-AI-GATEWAY-SIGNED-HEADERS':
      'x-ai-gateway-app-id;x-ai-gateway-timestamp;x-ai-gateway-nonce',
      'X-AI-GATEWAY-SIGNATURE': generateSignature(appKey, buf.toString())
    };
    return headers;
  }
}

Future<String> vivogpt(String text) async {
  const appId = '3035238278';
  const appKey = 'DMIBrukTGQlkgNYN';
  const uri = '/vivogpt/completions';
  const domain = 'api-ai.vivo.com.cn';
  const method = 'POST';
  final uuid = Uuid();
  final requestId = uuid.v4();
  print('requestId: $requestId');

  final queryParams = {'requestId': requestId};
  final queryStr = Uri(queryParameters: queryParams).query;

  // 构建请求体
  final data = {
    'prompt': text,
    'model': 'vivo-BlueLM-TB',
    'sessionId': uuid.v4(),
  };
  print(data['sessionId']);

  final headers =
  VivoAuth.generateAuthHeaders(appId, appKey, method, uri, queryStr);
  headers['Content-Type'] = 'application/json';

  final url = 'http://$domain$uri?$queryStr';
  final requestBodyString = jsonEncode(data);

  final response = await http.post(
    Uri.parse(url),
    headers: headers,
    body: requestBodyString,
  );

  if (response.statusCode == 200) {
    final responseBody = jsonDecode(response.body);
    final content = responseBody['data']['content'];
    return content;
  } else {
    print('Error response: ${response.statusCode}');
    print('Response body: ${response.body}');
    return 'Error: ${response.statusCode}';
  }
}